<script setup lang="ts">
import { ref, onDeactivated, onBeforeUnmount, onMounted, watch } from 'vue';
import { useRoute } from 'vue-router';
import TrafficLight from '@/components/devices/TrafficLight.vue';
import { Project } from '@/components/projects/Project';
import type { Part } from '@/types/Part';
import { getPartsAsync } from '@/utils/project-api';
import DeviceCards from './components/DeviceCards.vue';
import type { ProjectInfo, DistributionDeviceStatus } from './components/Components';
import { ElMessage } from 'element-plus';
import PolygonalLine from '@/components/common/lines/PolygonalLine.vue';
import type { Point } from '@/components/common/lines/types/Point';
import { useDeviceMaintenanceSignalRClientStore } from '@/stores/signalr-client';

const currentProjectId = ref<string>('');
const currentPartId = ref<string>('');
const partsOption = ref<Part[]>([]);
const projectOption = ref<ProjectInfo[]>([]);
const mixingTankStore = ref<Part[]>([]);

const anodeMixerRegex = /^[0-9]{1,3}#阳极搅拌机-[\w]{1,}$/;
const project = new Project();
const route = useRoute();
const clientStore = useDeviceMaintenanceSignalRClientStore();

if (!clientStore.isConnected()) {
  clientStore.connectServerAsync();
}

// 监听路由项目ID参数变化
watch(
  () => route.query.projectId,
  (newParam: any) => projectChange(newParam)
);
// 监听路由部件Id变化
watch(
  () => route.query.partId,
  (newParam: any) => partChange(newParam)
);

onMounted(() => {
  init();
  const { projectId, partId } = route.query;
  if (projectId && typeof projectId === 'string') {
    projectChange(projectId).then(() => {
      if (partId && typeof partId === 'string') partChange(partId);
    });
  }
});
// 初始化请求接口
const init = async () => {
  try {
    const resp: any = await project.getAsync(0, 1000);
    projectOption.value = resp;
  } catch (error) {
    if (error) return ElMessage.error(error || '获取项目列表错误！');
  }
};
/**
 * 搅拌电机
 */
const mixingMotor = ref<DistributionDeviceStatus>({
  status: 'green',
  title: '搅拌电机',
  partId: '',
  currentSpeed: {
    label: '当前转速',
    value: '--',
    unit: 'rpm'
  },
  currentLifespan: {
    label: '当前寿命',
    value: '--',
    unit: 'day'
  },
  warningValue: {
    label: '预警寿命',
    value: '--',
    unit: 'day'
  },
  stopValue: {
    label: '停机寿命',
    value: '--',
    unit: 'day'
  }
});

/**
 * 左真空滤芯
 */
const leftVacuumFilterCore = ref<DistributionDeviceStatus>({
  status: 'green',
  title: '左真空滤芯',
  partId: '',
  currentPressure: {
    label: '当前压强',
    value: '--',
    unit: 'kpa'
  },
  currentLifespan: {
    label: '当前寿命',
    value: '--',
    unit: 'day'
  },
  warningValue: {
    label: '预警寿命',
    value: '--',
    unit: 'day'
  },
  stopValue: {
    label: '停机寿命',
    value: '--',
    unit: 'day'
  }
});

/**
 * 中心轴
 */
const centerAxis = ref<DistributionDeviceStatus>({
  status: 'green',
  title: '中心轴',
  partId: '',
  currentElectricCurrent: {
    label: '当前电流',
    value: '--',
    unit: 'mA'
  },
  currentLifespan: {
    label: '当前寿命',
    value: '--',
    unit: 'day'
  },
  warningValue: {
    label: '预警寿命',
    value: '--',
    unit: 'day'
  },
  stopValue: {
    label: '停机寿命',
    value: '--',
    unit: 'day'
  }
});

/**
 * 分散电机
 */
const dispersionMotor = ref<DistributionDeviceStatus>({
  status: 'green',
  title: '分散电机',
  partId: '',
  currentSpeed: {
    label: '当前转速',
    value: '--',
    unit: 'rpm'
  },
  currentLifespan: {
    label: '当前寿命',
    value: '--',
    unit: 'day'
  },
  warningValue: {
    label: '预警寿命',
    value: '--',
    unit: 'day'
  },
  stopValue: {
    label: '停机寿命',
    value: '--',
    unit: 'day'
  }
});

/**
 * 右真空滤芯
 */
const rightVacuumFilterCore = ref<DistributionDeviceStatus>({
  status: 'green',
  title: '右真空滤芯',
  partId: '',
  currentPressure: {
    label: '当前压强',
    value: '--',
    unit: 'kpa'
  },
  currentLifespan: {
    label: '当前寿命',
    value: '--',
    unit: 'day'
  },
  warningValue: {
    label: '预警寿命',
    value: '--',
    unit: 'day'
  },
  stopValue: {
    label: '停机寿命',
    value: '--',
    unit: 'day'
  }
});

/**
 * 密封圈
 */
const sealingRing = ref<DistributionDeviceStatus>({
  status: 'green',
  title: '密封圈',
  partId: '',
  currentPressure: {
    label: '当前压强',
    value: '--',
    unit: 'kpa'
  },
  currentLifespan: {
    label: '当前寿命',
    value: '--',
    unit: 'day'
  },
  warningValue: {
    label: '预警寿命',
    value: '--',
    unit: 'day'
  },
  stopValue: {
    label: '停机寿命',
    value: '--',
    unit: 'day'
  }
});

// 搅拌电机
const points1: Point[] = [
  {
    x: 560,
    y: 160
  },
  {
    x: 670,
    y: 160
  },
  {
    x: 670,
    y: 190
  },
  {
    x: 730,
    y: 190
  },
];

// 左真空滤芯
const points2: Point[] = [
  {
    x: 560,
    y: 385
  },
  {
    x: 730,
    y: 385
  },
];

// 中心轴
const points3: Point[] = [
  {
    x: 560,
    y: 620
  },
  {
    x: 894,
    y: 620
  },
  {
    x: 894,
    y: 370
  },
];

// 分散电机
const points4: Point[] = [
{
    x: 1006,
    y: 160
  },
  {
    x: 1260,
    y: 160
  },
];

// 右真空滤芯
const points5: Point[] = [
{
    x: 1060,
    y: 385
  },
  {
    x: 1260,
    y: 385
  },
];
// 密封圈
const points6: Point[] = [
  {
    x: 950,
    y: 526
  },
  {
    x: 1150,
    y: 526
  },
  {
    x: 1150,
    y: 626
  },
  {
    x: 1260,
    y: 626
  },

];

interface Dictionary {
  [key: string]: any;
}

async function subscribeAsync() {
  const mixingMotorPart = mixingTankStore.value.find((item) => item.partName.endsWith('搅拌电机'));
  if (mixingMotorPart != null) {
    mixingMotor.value.partId = mixingMotorPart.id;
    await partSubscribeAsync(mixingMotor.value.partId);
  }

  const leftVacuumFilterCorePart = mixingTankStore.value.find((item) =>
    item.partName.endsWith('左真空滤芯')
  );
  if (leftVacuumFilterCorePart != null) {
    leftVacuumFilterCore.value.partId = leftVacuumFilterCorePart.id;
    await partSubscribeAsync(leftVacuumFilterCore.value.partId);
  }

  const centerAxisPart = mixingTankStore.value.find((item) => item.partName.endsWith('中心轴'));
  if (centerAxisPart != null) {
    centerAxis.value.partId = centerAxisPart.id;
    await partSubscribeAsync(centerAxis.value.partId);
  }

  const dispersionMotorPart = mixingTankStore.value.find((item) =>
    item.partName.endsWith('分散电机')
  );
  if (dispersionMotorPart != null) {
    dispersionMotor.value.partId = dispersionMotorPart.id;
    await partSubscribeAsync(dispersionMotor.value.partId);
  }

  const rightVacuumFilterCorePart = mixingTankStore.value.find((item) =>
    item.partName.endsWith('右真空滤芯')
  );
  if (rightVacuumFilterCorePart != null) {
    rightVacuumFilterCore.value.partId = rightVacuumFilterCorePart.id;
    await partSubscribeAsync(rightVacuumFilterCore.value.partId);
  }

  const sealingRingPart = mixingTankStore.value.find((item) => item.partName.endsWith('密封圈'));
  if (sealingRingPart != null) {
    sealingRing.value.partId = sealingRingPart.id;
    await partSubscribeAsync(sealingRing.value.partId);
  }
}

async function partSubscribeAsync(partId: string) {
  await clientStore.subscribeAsync(partId, (result) => {
    const propertyToUpdate = taskToUpdatePropertyMap[result.taskName];
    if (propertyToUpdate) {
      propertyToUpdate.value = result.value;
    }
  });
}

async function unsubscribeAsync() {
  await clientStore.unsubscribeAsync(mixingMotor.value.partId);
  await clientStore.unsubscribeAsync(leftVacuumFilterCore.value.partId);
  await clientStore.unsubscribeAsync(centerAxis.value.partId);
  await clientStore.unsubscribeAsync(dispersionMotor.value.partId);
  await clientStore.unsubscribeAsync(rightVacuumFilterCore.value.partId);
  await clientStore.unsubscribeAsync(sealingRing.value.partId);
}

const taskToUpdatePropertyMap: Dictionary = {
  搅拌电机当前转速: mixingMotor.value.currentSpeed,
  搅拌电机当前寿命: mixingMotor.value.currentLifespan,
  搅拌电机预警寿命: mixingMotor.value.warningValue,
  搅拌电机停机寿命: mixingMotor.value.stopValue,
  左真空滤芯当前压强: leftVacuumFilterCore.value.currentPressure,
  左真空滤芯当前寿命: leftVacuumFilterCore.value.currentLifespan,
  左真空滤芯预警寿命: leftVacuumFilterCore.value.warningValue,
  左真空滤芯停机寿命: leftVacuumFilterCore.value.stopValue,
  中心轴当前电流: centerAxis.value.currentElectricCurrent,
  中心轴当前寿命: centerAxis.value.currentLifespan,
  中心轴预警寿命: centerAxis.value.warningValue,
  中心轴停机寿命: centerAxis.value.stopValue,
  分散电机当前转速: dispersionMotor.value.currentSpeed,
  分散电机当前寿命: dispersionMotor.value.currentLifespan,
  分散电机预警寿命: dispersionMotor.value.warningValue,
  分散电机停机寿命: dispersionMotor.value.stopValue,
  右真空滤芯当前压强: rightVacuumFilterCore.value.currentPressure,
  右真空滤芯当前寿命: rightVacuumFilterCore.value.currentLifespan,
  右真空滤芯预警寿命: rightVacuumFilterCore.value.warningValue,
  右真空滤芯停机寿命: rightVacuumFilterCore.value.stopValue,
  密封圈当前压强: sealingRing.value.currentPressure,
  密封圈当前寿命: sealingRing.value.currentLifespan,
  密封圈预警寿命: sealingRing.value.warningValue,
  密封圈停机寿命: sealingRing.value.stopValue
};

// 监听项目查询搅拌机
const projectChange = async (value: string) => {
  if (value) {
    currentProjectId.value = value;
    // 项目改变清空选择部件
    currentPartId.value = '';
    // 获取全部部件
    const resp: any = await getPartsAsync(value);
    if (resp.message) return ElMessage.error(resp.message || '获取搅拌机列表错误！');
    mixingTankStore.value = resp.result;
    // 过滤出对应部件
    partsOption.value = resp.result.filter((item: any) => {
      return !item.partOwnerId && anodeMixerRegex.test(item.partName);
    });
  }
};

// 监听搅拌机查询对应值
const partChange = (value: string) => {
  if (value) {
    currentPartId.value = value;
    subscribeAsync();
  }
};

// 在从 DOM 上移除、进入缓存
// 以及组件卸载时调用
onDeactivated(async () => {
  await unsubscribeAsync();
});

onBeforeUnmount(async () => {
  await unsubscribeAsync();
});
</script>

<template>
  <main class="main-container">
    <div class="search-container">
      <div class="d-f">
        <el-text class="mx-1">项目名称:</el-text>
        <el-select class="select-project" @change="projectChange" v-model="currentProjectId">
          <el-option
            v-for="item in projectOption"
            :key="item.id"
            :label="item.projectName"
            :value="item.id"
          />
        </el-select>
      </div>
      <div class="current-part-name">
        <el-text class="mx-1">搅拌机:</el-text>
        <el-select class="select-part" @change="partChange" v-model="currentPartId">
          <el-option
            v-for="item in partsOption"
            :key="item.id"
            :label="item.partName"
            :value="item.id"
          />
        </el-select>
      </div>
    </div>
    <div class="content-container">
      <!-- <div class="content">
        <TrafficLight :color="'red'"></TrafficLight>
      </div> -->
      <div class="content-title">阳极搅拌机</div>
      <el-card class="content-status" shadow="hover">
        <div class="d-f">
          <div class="stir-color">
            <TrafficLight :color="''"></TrafficLight>
            <span class="title">搅拌电机</span>
          </div>
          <div class="vacuumLeft-color">
            <TrafficLight :color="''"></TrafficLight>
            <span class="title">真空滤芯(左)</span>
          </div>
          <div class="vacuumLeft-color">
            <TrafficLight :color="''"></TrafficLight>
            <span class="title">分散电机</span>
          </div>
        </div>
        <div class="seal-color">
          <div class="stir-color">
            <TrafficLight :color="''"></TrafficLight>
            <span class="title">密封圈</span>
          </div>
          <div class="vacuumLeft-color">
            <TrafficLight :color="''"></TrafficLight>
            <span class="title">真空滤芯(右)</span>
          </div>
        </div>
      </el-card>
      <el-card class="content-right" shadow="hover">
        <div class="right-top">部件日志信息</div>
        <div>
          <div class="right-center">密封圈：压强正常。</div>
        </div>
        <div>
          <div class="right-foot">左真空滤芯：压强波动超过设定值 10 kpa 。</div>
        </div>
      </el-card>
      <DeviceCards
        :items="[
          mixingMotor,
          leftVacuumFilterCore,
          centerAxis,
          dispersionMotor,
          rightVacuumFilterCore,
          sealingRing
        ]"
      />
      <img src="@/assets/img/mixing/anode-mixing.png" class="main-img" />
      <div class="lines-container">
        <PolygonalLine :points="points1" line-width="2px" radius2="4px"></PolygonalLine>
        <PolygonalLine :points="points2" line-width="2px" radius2="4px"></PolygonalLine>
        <PolygonalLine :points="points3" line-width="2px" radius2="4px"></PolygonalLine>
        <PolygonalLine :points="points4" line-width="2px" radius2="4px"></PolygonalLine>
        <PolygonalLine :points="points5" line-width="2px" radius2="4px"></PolygonalLine>
        <PolygonalLine :points="points6" line-width="2px" radius2="4px"></PolygonalLine>
      </div>
    </div>
  </main>
</template>

<style scoped lang="scss">
.main-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #100b30;
  border-radius: 5px;
}

.content-container {
  padding: 0px 30px 20px 30px;
  border-radius: 5px;
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  .content {
    position: absolute;
    left: 37%;
    z-index: 99;
    top: 46%;
  }
  :deep(.el-card) {
      border-radius: 10px;
      border: 1px;
      background: linear-gradient(90deg, rgb(47 18 115) 0%, #54277da8 100%);
      box-shadow: 0px 0px 5px #6167e4;
      color: #fff;
      &:hover {
        cursor: pointer;
        box-shadow: 0px 0px 10px #ee82ee;
      }
    }
  .content-title {
    position: absolute;
    left: 48.5%;
    top: 10px;
    font-weight: bold;
    font-size: 30px;
    color: #fff;
    transform: translateX(-50%);
  }
  .content-status {
    width: 300px;
    height: calc(100vh - 150px);
    position: absolute;
    left: 15px;
    bottom: 15px;
    .stir-color {
      display: flex;
      align-items: center;
    }
    .vacuumLeft-color {
      display: flex;
      align-items: center;
      margin-left: 20px;
    }
    .title {
      writing-mode: vertical-lr;
    }
    .seal-color {
      display: flex;
      margin-top: 20px;
    }
  }
  .lines-container {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 99;
      pointer-events: none;
    }
  .content-right {
    width: 300px;
    height: calc(100vh - 150px);
    position: absolute;
    right: 15px;
    bottom: 15px;
    .right-top {
      font-weight: bold;
    }
    .right-center {
      display: inline;
      color: green;
    }
    .right-foot {
      display: inline;
      color: red;
    }
  }
  .content-main {
    .content-main-title {
      margin-top: 10px;
      .title {
        display: inline-block;
        width: 100px;
      }
      .value {
        display: inline-block;
      }
    }
  }
  .content-main.content1 {
    width: 200px;
    position: absolute;
    top: 8%;
    left: 19.3%;
  }
  .content-main.content2 {
    width: 200px;
    position: absolute;
    top: 38%;
    left: 19.3%;
  }
  .content-main.content3 {
    width: 200px;
    position: absolute;
    top: 68%;
    left: 19.3%;
  }
  .content-main.content4 {
    width: 200px;
    position: absolute;
    top: 8%;
    left: 68.4%;
  }
  .content-main.content5 {
    width: 200px;
    position: absolute;
    top: 38%;
    left: 68.4%;
  }
  .content-main.content6 {
    width: 200px;
    position: absolute;
    top: 68%;
    left: 68.4%;
  }
  .main-img {
    position: absolute;
    left: 50%;
    top: 50%;
    // width: 800px;
    width: 42%;
    // height: 100%;
    transform: translate(-50%, -50%);
  }
}

.search-container {
  padding: 15px 30px 0px 15px;
  border-radius: 5px;
  display: flex;
  flex-direction: row;
  .select-project {
    width: 200px;
    margin-left: 8px;
    &:focus {
      outline: unset;
    }
    :deep(.el-select__wrapper:focus) {
      outline: unset;
    }
  }
  .current-part-name {
    margin-left: 20px;
    display: flex;
    .select-part {
      width: 240px;
      margin-left: 8px;
      &:focus {
        outline: unset;
      }
      :deep(.el-select__wrapper:focus) {
        outline: unset;
      }
    }
  }
}
.d-f {
  display: flex;
}
</style>
